using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using SanJ.FreeCare.EntityFrameworkCore;

namespace SanJ.FreeCare.Medications
{
    public abstract class EfCoreMedicationRepositoryBase : EfCoreRepository<FreeCareDbContext, Medication, Guid>
    {
        public EfCoreMedicationRepositoryBase(IDbContextProvider<FreeCareDbContext> dbContextProvider)
            : base(dbContextProvider)
        {

        }

        public virtual async Task DeleteAllAsync(
            string? filterText = null,
                        string? code = null,
            string? statusCode = null,
            string? keyWord = null,
            string? productName = null,
            string? productNamePY = null,
            string? productNameWB = null,
            string? productNameEN = null,
            string? alias = null,
            string? aliasPY = null,
            string? aliasWB = null,
            string? aliasEN = null,
            string? scientificName = null,
            string? scientificNamePY = null,
            string? scientificNameWB = null,
            string? scientificNameEN = null,
            string? antiLevelCode = null,
            string? antiClassCode1 = null,
            string? antiClassCode2 = null,
            string? anitDDDUnitCode = null,
            decimal? anitDDDValueMin = null,
            decimal? anitDDDValueMax = null,
            decimal? antiOnceMinValueMin = null,
            decimal? antiOnceMinValueMax = null,
            decimal? antiOnceMaxValueMin = null,
            decimal? antiOnceMaxValueMax = null,
            string? antiOnceUnitCode = null,
            int? antiFrequencyMinMin = null,
            int? antiFrequencyMinMax = null,
            int? antiFrequencyMaxMin = null,
            int? antiFrequencyMaxMax = null,
            string? gBCode = null,
            string? typeCode = null,
            string? classCode = null,
            string? feeTypeCode = null,
            string? specialTypeCode = null,
            string? levelCode = null,
            string? doseFormCode = null,
            string? specification = null,
            string? baseUnitCode = null,
            string? clinicSaleUnitCode = null,
            decimal? clinicSaleVolumeMin = null,
            decimal? clinicSaleVolumeMax = null,
            string? inpatientSaleUnitCode = null,
            string? inpatientSaleVolume = null,
            string? transportUnitCode = null,
            string? transportVolume = null,
            string? defaultDoseUnitCode = null,
            decimal? defultDoseVolumeMin = null,
            decimal? defultDoseVolumeMax = null,
            string? secondDoseUnitCode = null,
            decimal? secondDoseVolumeMin = null,
            decimal? secondDoseVolumeMax = null,
            decimal? retailPriceMin = null,
            decimal? retailPriceMax = null,
            string? defaultUsageCode = null,
            string? defaultFrequencyCode = null,
            decimal? defaultDoseVolumeMin = null,
            decimal? defaultDoseVolumeMax = null,
            string? skinTestFlag = null,
            string? skinTestNeedFlag = null,
            string? skinTestTypeFlag = null,
            string? skinTestCode = null,
            CancellationToken cancellationToken = default)
        {

            var query = await GetQueryableAsync();

            query = ApplyFilter(query, filterText, code, statusCode, keyWord, productName, productNamePY, productNameWB, productNameEN, alias, aliasPY, aliasWB, aliasEN, scientificName, scientificNamePY, scientificNameWB, scientificNameEN, antiLevelCode, antiClassCode1, antiClassCode2, anitDDDUnitCode, anitDDDValueMin, anitDDDValueMax, antiOnceMinValueMin, antiOnceMinValueMax, antiOnceMaxValueMin, antiOnceMaxValueMax, antiOnceUnitCode, antiFrequencyMinMin, antiFrequencyMinMax, antiFrequencyMaxMin, antiFrequencyMaxMax, gBCode, typeCode, classCode, feeTypeCode, specialTypeCode, levelCode, doseFormCode, specification, baseUnitCode, clinicSaleUnitCode, clinicSaleVolumeMin, clinicSaleVolumeMax, inpatientSaleUnitCode, inpatientSaleVolume, transportUnitCode, transportVolume, defaultDoseUnitCode, defultDoseVolumeMin, defultDoseVolumeMax, secondDoseUnitCode, secondDoseVolumeMin, secondDoseVolumeMax, retailPriceMin, retailPriceMax, defaultUsageCode, defaultFrequencyCode, defaultDoseVolumeMin, defaultDoseVolumeMax, skinTestFlag, skinTestNeedFlag, skinTestTypeFlag, skinTestCode);

            var ids = query.Select(x => x.Id);
            await DeleteManyAsync(ids, cancellationToken: GetCancellationToken(cancellationToken));
        }

        public virtual async Task<List<Medication>> GetListAsync(
            string? filterText = null,
            string? code = null,
            string? statusCode = null,
            string? keyWord = null,
            string? productName = null,
            string? productNamePY = null,
            string? productNameWB = null,
            string? productNameEN = null,
            string? alias = null,
            string? aliasPY = null,
            string? aliasWB = null,
            string? aliasEN = null,
            string? scientificName = null,
            string? scientificNamePY = null,
            string? scientificNameWB = null,
            string? scientificNameEN = null,
            string? antiLevelCode = null,
            string? antiClassCode1 = null,
            string? antiClassCode2 = null,
            string? anitDDDUnitCode = null,
            decimal? anitDDDValueMin = null,
            decimal? anitDDDValueMax = null,
            decimal? antiOnceMinValueMin = null,
            decimal? antiOnceMinValueMax = null,
            decimal? antiOnceMaxValueMin = null,
            decimal? antiOnceMaxValueMax = null,
            string? antiOnceUnitCode = null,
            int? antiFrequencyMinMin = null,
            int? antiFrequencyMinMax = null,
            int? antiFrequencyMaxMin = null,
            int? antiFrequencyMaxMax = null,
            string? gBCode = null,
            string? typeCode = null,
            string? classCode = null,
            string? feeTypeCode = null,
            string? specialTypeCode = null,
            string? levelCode = null,
            string? doseFormCode = null,
            string? specification = null,
            string? baseUnitCode = null,
            string? clinicSaleUnitCode = null,
            decimal? clinicSaleVolumeMin = null,
            decimal? clinicSaleVolumeMax = null,
            string? inpatientSaleUnitCode = null,
            string? inpatientSaleVolume = null,
            string? transportUnitCode = null,
            string? transportVolume = null,
            string? defaultDoseUnitCode = null,
            decimal? defultDoseVolumeMin = null,
            decimal? defultDoseVolumeMax = null,
            string? secondDoseUnitCode = null,
            decimal? secondDoseVolumeMin = null,
            decimal? secondDoseVolumeMax = null,
            decimal? retailPriceMin = null,
            decimal? retailPriceMax = null,
            string? defaultUsageCode = null,
            string? defaultFrequencyCode = null,
            decimal? defaultDoseVolumeMin = null,
            decimal? defaultDoseVolumeMax = null,
            string? skinTestFlag = null,
            string? skinTestNeedFlag = null,
            string? skinTestTypeFlag = null,
            string? skinTestCode = null,
            string? sorting = null,
            int maxResultCount = int.MaxValue,
            int skipCount = 0,
            CancellationToken cancellationToken = default)
        {
            var query = ApplyFilter((await GetQueryableAsync()), filterText, code, statusCode, keyWord, productName, productNamePY, productNameWB, productNameEN, alias, aliasPY, aliasWB, aliasEN, scientificName, scientificNamePY, scientificNameWB, scientificNameEN, antiLevelCode, antiClassCode1, antiClassCode2, anitDDDUnitCode, anitDDDValueMin, anitDDDValueMax, antiOnceMinValueMin, antiOnceMinValueMax, antiOnceMaxValueMin, antiOnceMaxValueMax, antiOnceUnitCode, antiFrequencyMinMin, antiFrequencyMinMax, antiFrequencyMaxMin, antiFrequencyMaxMax, gBCode, typeCode, classCode, feeTypeCode, specialTypeCode, levelCode, doseFormCode, specification, baseUnitCode, clinicSaleUnitCode, clinicSaleVolumeMin, clinicSaleVolumeMax, inpatientSaleUnitCode, inpatientSaleVolume, transportUnitCode, transportVolume, defaultDoseUnitCode, defultDoseVolumeMin, defultDoseVolumeMax, secondDoseUnitCode, secondDoseVolumeMin, secondDoseVolumeMax, retailPriceMin, retailPriceMax, defaultUsageCode, defaultFrequencyCode, defaultDoseVolumeMin, defaultDoseVolumeMax, skinTestFlag, skinTestNeedFlag, skinTestTypeFlag, skinTestCode);
            query = query.OrderBy(string.IsNullOrWhiteSpace(sorting) ? MedicationConsts.GetDefaultSorting(false) : sorting);
            return await query.PageBy(skipCount, maxResultCount).ToListAsync(cancellationToken);
        }

        public virtual async Task<long> GetCountAsync(
            string? filterText = null,
            string? code = null,
            string? statusCode = null,
            string? keyWord = null,
            string? productName = null,
            string? productNamePY = null,
            string? productNameWB = null,
            string? productNameEN = null,
            string? alias = null,
            string? aliasPY = null,
            string? aliasWB = null,
            string? aliasEN = null,
            string? scientificName = null,
            string? scientificNamePY = null,
            string? scientificNameWB = null,
            string? scientificNameEN = null,
            string? antiLevelCode = null,
            string? antiClassCode1 = null,
            string? antiClassCode2 = null,
            string? anitDDDUnitCode = null,
            decimal? anitDDDValueMin = null,
            decimal? anitDDDValueMax = null,
            decimal? antiOnceMinValueMin = null,
            decimal? antiOnceMinValueMax = null,
            decimal? antiOnceMaxValueMin = null,
            decimal? antiOnceMaxValueMax = null,
            string? antiOnceUnitCode = null,
            int? antiFrequencyMinMin = null,
            int? antiFrequencyMinMax = null,
            int? antiFrequencyMaxMin = null,
            int? antiFrequencyMaxMax = null,
            string? gBCode = null,
            string? typeCode = null,
            string? classCode = null,
            string? feeTypeCode = null,
            string? specialTypeCode = null,
            string? levelCode = null,
            string? doseFormCode = null,
            string? specification = null,
            string? baseUnitCode = null,
            string? clinicSaleUnitCode = null,
            decimal? clinicSaleVolumeMin = null,
            decimal? clinicSaleVolumeMax = null,
            string? inpatientSaleUnitCode = null,
            string? inpatientSaleVolume = null,
            string? transportUnitCode = null,
            string? transportVolume = null,
            string? defaultDoseUnitCode = null,
            decimal? defultDoseVolumeMin = null,
            decimal? defultDoseVolumeMax = null,
            string? secondDoseUnitCode = null,
            decimal? secondDoseVolumeMin = null,
            decimal? secondDoseVolumeMax = null,
            decimal? retailPriceMin = null,
            decimal? retailPriceMax = null,
            string? defaultUsageCode = null,
            string? defaultFrequencyCode = null,
            decimal? defaultDoseVolumeMin = null,
            decimal? defaultDoseVolumeMax = null,
            string? skinTestFlag = null,
            string? skinTestNeedFlag = null,
            string? skinTestTypeFlag = null,
            string? skinTestCode = null,
            CancellationToken cancellationToken = default)
        {
            var query = ApplyFilter((await GetDbSetAsync()), filterText, code, statusCode, keyWord, productName, productNamePY, productNameWB, productNameEN, alias, aliasPY, aliasWB, aliasEN, scientificName, scientificNamePY, scientificNameWB, scientificNameEN, antiLevelCode, antiClassCode1, antiClassCode2, anitDDDUnitCode, anitDDDValueMin, anitDDDValueMax, antiOnceMinValueMin, antiOnceMinValueMax, antiOnceMaxValueMin, antiOnceMaxValueMax, antiOnceUnitCode, antiFrequencyMinMin, antiFrequencyMinMax, antiFrequencyMaxMin, antiFrequencyMaxMax, gBCode, typeCode, classCode, feeTypeCode, specialTypeCode, levelCode, doseFormCode, specification, baseUnitCode, clinicSaleUnitCode, clinicSaleVolumeMin, clinicSaleVolumeMax, inpatientSaleUnitCode, inpatientSaleVolume, transportUnitCode, transportVolume, defaultDoseUnitCode, defultDoseVolumeMin, defultDoseVolumeMax, secondDoseUnitCode, secondDoseVolumeMin, secondDoseVolumeMax, retailPriceMin, retailPriceMax, defaultUsageCode, defaultFrequencyCode, defaultDoseVolumeMin, defaultDoseVolumeMax, skinTestFlag, skinTestNeedFlag, skinTestTypeFlag, skinTestCode);
            return await query.LongCountAsync(GetCancellationToken(cancellationToken));
        }

        protected virtual IQueryable<Medication> ApplyFilter(
            IQueryable<Medication> query,
            string? filterText = null,
            string? code = null,
            string? statusCode = null,
            string? keyWord = null,
            string? productName = null,
            string? productNamePY = null,
            string? productNameWB = null,
            string? productNameEN = null,
            string? alias = null,
            string? aliasPY = null,
            string? aliasWB = null,
            string? aliasEN = null,
            string? scientificName = null,
            string? scientificNamePY = null,
            string? scientificNameWB = null,
            string? scientificNameEN = null,
            string? antiLevelCode = null,
            string? antiClassCode1 = null,
            string? antiClassCode2 = null,
            string? anitDDDUnitCode = null,
            decimal? anitDDDValueMin = null,
            decimal? anitDDDValueMax = null,
            decimal? antiOnceMinValueMin = null,
            decimal? antiOnceMinValueMax = null,
            decimal? antiOnceMaxValueMin = null,
            decimal? antiOnceMaxValueMax = null,
            string? antiOnceUnitCode = null,
            int? antiFrequencyMinMin = null,
            int? antiFrequencyMinMax = null,
            int? antiFrequencyMaxMin = null,
            int? antiFrequencyMaxMax = null,
            string? gBCode = null,
            string? typeCode = null,
            string? classCode = null,
            string? feeTypeCode = null,
            string? specialTypeCode = null,
            string? levelCode = null,
            string? doseFormCode = null,
            string? specification = null,
            string? baseUnitCode = null,
            string? clinicSaleUnitCode = null,
            decimal? clinicSaleVolumeMin = null,
            decimal? clinicSaleVolumeMax = null,
            string? inpatientSaleUnitCode = null,
            string? inpatientSaleVolume = null,
            string? transportUnitCode = null,
            string? transportVolume = null,
            string? defaultDoseUnitCode = null,
            decimal? defultDoseVolumeMin = null,
            decimal? defultDoseVolumeMax = null,
            string? secondDoseUnitCode = null,
            decimal? secondDoseVolumeMin = null,
            decimal? secondDoseVolumeMax = null,
            decimal? retailPriceMin = null,
            decimal? retailPriceMax = null,
            string? defaultUsageCode = null,
            string? defaultFrequencyCode = null,
            decimal? defaultDoseVolumeMin = null,
            decimal? defaultDoseVolumeMax = null,
            string? skinTestFlag = null,
            string? skinTestNeedFlag = null,
            string? skinTestTypeFlag = null,
            string? skinTestCode = null)
        {
            return query
                    .WhereIf(!string.IsNullOrWhiteSpace(filterText), e => e.Code!.Contains(filterText!) || e.StatusCode!.Contains(filterText!) || e.KeyWord!.Contains(filterText!) || e.ProductName!.Contains(filterText!) || e.ProductNamePY!.Contains(filterText!) || e.ProductNameWB!.Contains(filterText!) || e.ProductNameEN!.Contains(filterText!) || e.Alias!.Contains(filterText!) || e.AliasPY!.Contains(filterText!) || e.AliasWB!.Contains(filterText!) || e.AliasEN!.Contains(filterText!) || e.ScientificName!.Contains(filterText!) || e.ScientificNamePY!.Contains(filterText!) || e.ScientificNameWB!.Contains(filterText!) || e.ScientificNameEN!.Contains(filterText!) || e.AntiLevelCode!.Contains(filterText!) || e.AntiClassCode1!.Contains(filterText!) || e.AntiClassCode2!.Contains(filterText!) || e.AnitDDDUnitCode!.Contains(filterText!) || e.AntiOnceUnitCode!.Contains(filterText!) || e.GBCode!.Contains(filterText!) || e.TypeCode!.Contains(filterText!) || e.ClassCode!.Contains(filterText!) || e.FeeTypeCode!.Contains(filterText!) || e.SpecialTypeCode!.Contains(filterText!) || e.LevelCode!.Contains(filterText!) || e.DoseFormCode!.Contains(filterText!) || e.Specification!.Contains(filterText!) || e.BaseUnitCode!.Contains(filterText!) || e.ClinicSaleUnitCode!.Contains(filterText!) || e.InpatientSaleUnitCode!.Contains(filterText!) || e.InpatientSaleVolume!.Contains(filterText!) || e.TransportUnitCode!.Contains(filterText!) || e.TransportVolume!.Contains(filterText!) || e.DefaultDoseUnitCode!.Contains(filterText!) || e.SecondDoseUnitCode!.Contains(filterText!) || e.DefaultUsageCode!.Contains(filterText!) || e.DefaultFrequencyCode!.Contains(filterText!) || e.SkinTestFlag!.Contains(filterText!) || e.SkinTestNeedFlag!.Contains(filterText!) || e.SkinTestTypeFlag!.Contains(filterText!) || e.SkinTestCode!.Contains(filterText!))
                    .WhereIf(!string.IsNullOrWhiteSpace(code), e => e.Code.Contains(code))
                    .WhereIf(!string.IsNullOrWhiteSpace(statusCode), e => e.StatusCode.Contains(statusCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(keyWord), e => e.KeyWord.Contains(keyWord))
                    .WhereIf(!string.IsNullOrWhiteSpace(productName), e => e.ProductName.Contains(productName))
                    .WhereIf(!string.IsNullOrWhiteSpace(productNamePY), e => e.ProductNamePY.Contains(productNamePY))
                    .WhereIf(!string.IsNullOrWhiteSpace(productNameWB), e => e.ProductNameWB.Contains(productNameWB))
                    .WhereIf(!string.IsNullOrWhiteSpace(productNameEN), e => e.ProductNameEN.Contains(productNameEN))
                    .WhereIf(!string.IsNullOrWhiteSpace(alias), e => e.Alias.Contains(alias))
                    .WhereIf(!string.IsNullOrWhiteSpace(aliasPY), e => e.AliasPY.Contains(aliasPY))
                    .WhereIf(!string.IsNullOrWhiteSpace(aliasWB), e => e.AliasWB.Contains(aliasWB))
                    .WhereIf(!string.IsNullOrWhiteSpace(aliasEN), e => e.AliasEN.Contains(aliasEN))
                    .WhereIf(!string.IsNullOrWhiteSpace(scientificName), e => e.ScientificName.Contains(scientificName))
                    .WhereIf(!string.IsNullOrWhiteSpace(scientificNamePY), e => e.ScientificNamePY.Contains(scientificNamePY))
                    .WhereIf(!string.IsNullOrWhiteSpace(scientificNameWB), e => e.ScientificNameWB.Contains(scientificNameWB))
                    .WhereIf(!string.IsNullOrWhiteSpace(scientificNameEN), e => e.ScientificNameEN.Contains(scientificNameEN))
                    .WhereIf(!string.IsNullOrWhiteSpace(antiLevelCode), e => e.AntiLevelCode.Contains(antiLevelCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(antiClassCode1), e => e.AntiClassCode1.Contains(antiClassCode1))
                    .WhereIf(!string.IsNullOrWhiteSpace(antiClassCode2), e => e.AntiClassCode2.Contains(antiClassCode2))
                    .WhereIf(!string.IsNullOrWhiteSpace(anitDDDUnitCode), e => e.AnitDDDUnitCode.Contains(anitDDDUnitCode))
                    .WhereIf(anitDDDValueMin.HasValue, e => e.AnitDDDValue >= anitDDDValueMin!.Value)
                    .WhereIf(anitDDDValueMax.HasValue, e => e.AnitDDDValue <= anitDDDValueMax!.Value)
                    .WhereIf(antiOnceMinValueMin.HasValue, e => e.AntiOnceMinValue >= antiOnceMinValueMin!.Value)
                    .WhereIf(antiOnceMinValueMax.HasValue, e => e.AntiOnceMinValue <= antiOnceMinValueMax!.Value)
                    .WhereIf(antiOnceMaxValueMin.HasValue, e => e.AntiOnceMaxValue >= antiOnceMaxValueMin!.Value)
                    .WhereIf(antiOnceMaxValueMax.HasValue, e => e.AntiOnceMaxValue <= antiOnceMaxValueMax!.Value)
                    .WhereIf(!string.IsNullOrWhiteSpace(antiOnceUnitCode), e => e.AntiOnceUnitCode.Contains(antiOnceUnitCode))
                    .WhereIf(antiFrequencyMinMin.HasValue, e => e.AntiFrequencyMin >= antiFrequencyMinMin!.Value)
                    .WhereIf(antiFrequencyMinMax.HasValue, e => e.AntiFrequencyMin <= antiFrequencyMinMax!.Value)
                    .WhereIf(antiFrequencyMaxMin.HasValue, e => e.AntiFrequencyMax >= antiFrequencyMaxMin!.Value)
                    .WhereIf(antiFrequencyMaxMax.HasValue, e => e.AntiFrequencyMax <= antiFrequencyMaxMax!.Value)
                    .WhereIf(!string.IsNullOrWhiteSpace(gBCode), e => e.GBCode.Contains(gBCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(typeCode), e => e.TypeCode.Contains(typeCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(classCode), e => e.ClassCode.Contains(classCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(feeTypeCode), e => e.FeeTypeCode.Contains(feeTypeCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(specialTypeCode), e => e.SpecialTypeCode.Contains(specialTypeCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(levelCode), e => e.LevelCode.Contains(levelCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(doseFormCode), e => e.DoseFormCode.Contains(doseFormCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(specification), e => e.Specification.Contains(specification))
                    .WhereIf(!string.IsNullOrWhiteSpace(baseUnitCode), e => e.BaseUnitCode.Contains(baseUnitCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(clinicSaleUnitCode), e => e.ClinicSaleUnitCode.Contains(clinicSaleUnitCode))
                    .WhereIf(clinicSaleVolumeMin.HasValue, e => e.ClinicSaleVolume >= clinicSaleVolumeMin!.Value)
                    .WhereIf(clinicSaleVolumeMax.HasValue, e => e.ClinicSaleVolume <= clinicSaleVolumeMax!.Value)
                    .WhereIf(!string.IsNullOrWhiteSpace(inpatientSaleUnitCode), e => e.InpatientSaleUnitCode.Contains(inpatientSaleUnitCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(inpatientSaleVolume), e => e.InpatientSaleVolume.Contains(inpatientSaleVolume))
                    .WhereIf(!string.IsNullOrWhiteSpace(transportUnitCode), e => e.TransportUnitCode.Contains(transportUnitCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(transportVolume), e => e.TransportVolume.Contains(transportVolume))
                    .WhereIf(!string.IsNullOrWhiteSpace(defaultDoseUnitCode), e => e.DefaultDoseUnitCode.Contains(defaultDoseUnitCode))
                    .WhereIf(defultDoseVolumeMin.HasValue, e => e.DefultDoseVolume >= defultDoseVolumeMin!.Value)
                    .WhereIf(defultDoseVolumeMax.HasValue, e => e.DefultDoseVolume <= defultDoseVolumeMax!.Value)
                    .WhereIf(!string.IsNullOrWhiteSpace(secondDoseUnitCode), e => e.SecondDoseUnitCode.Contains(secondDoseUnitCode))
                    .WhereIf(secondDoseVolumeMin.HasValue, e => e.SecondDoseVolume >= secondDoseVolumeMin!.Value)
                    .WhereIf(secondDoseVolumeMax.HasValue, e => e.SecondDoseVolume <= secondDoseVolumeMax!.Value)
                    .WhereIf(retailPriceMin.HasValue, e => e.RetailPrice >= retailPriceMin!.Value)
                    .WhereIf(retailPriceMax.HasValue, e => e.RetailPrice <= retailPriceMax!.Value)
                    .WhereIf(!string.IsNullOrWhiteSpace(defaultUsageCode), e => e.DefaultUsageCode.Contains(defaultUsageCode))
                    .WhereIf(!string.IsNullOrWhiteSpace(defaultFrequencyCode), e => e.DefaultFrequencyCode.Contains(defaultFrequencyCode))
                    .WhereIf(defaultDoseVolumeMin.HasValue, e => e.DefaultDoseVolume >= defaultDoseVolumeMin!.Value)
                    .WhereIf(defaultDoseVolumeMax.HasValue, e => e.DefaultDoseVolume <= defaultDoseVolumeMax!.Value)
                    .WhereIf(!string.IsNullOrWhiteSpace(skinTestFlag), e => e.SkinTestFlag.Contains(skinTestFlag))
                    .WhereIf(!string.IsNullOrWhiteSpace(skinTestNeedFlag), e => e.SkinTestNeedFlag.Contains(skinTestNeedFlag))
                    .WhereIf(!string.IsNullOrWhiteSpace(skinTestTypeFlag), e => e.SkinTestTypeFlag.Contains(skinTestTypeFlag))
                    .WhereIf(!string.IsNullOrWhiteSpace(skinTestCode), e => e.SkinTestCode.Contains(skinTestCode));
        }
    }
}